#!/usr/bin/lua
function split(str, delimiter)
    local fs = delimiter
    if not fs or "" == string.gsub(fs," ","") then
                fs="%s"
        end
    if str==nil or str=="" or delimiter==nil then
        return nil
    end

    local result = {}
        for match in string.gmatch((str..delimiter),"[^"..fs.."]+") do
        table.insert(result, match)
    end
    return result
end
function get_arp()
    local res = {}
    local num = 0
    local f_arp = "/proc/net/arp"
    if 0 == os.execute("test -f "..f_arp) then 
        local cmd = "grep br-lan "..f_arp.." | grep 0x2"
        local fd = io.popen(cmd, "r");
        local row = nil
        local mac = nil
        if fd then
            while true do
                local line = nil
                line = fd:read("*l")
                if not line or #line==0 then break end
                row=split(line," ")
                mac = string.upper(row[4])
                res[ mac ] = row[1]
            end
        end
        fd:close()
    end
    return res
end
function get_assoclist()
    local res = {}
    local util = require("luci.util")
    local ifn_list=util.exec([[ls /sys/devices/virtual/net/ | grep ra | tr -s '\n' ' ']])
    local ifn_t = split(ifn_list," ")
    for _,ifn in pairs(ifn_t) do
        local cmd = "iwinfo "..ifn.." assoclist | grep -E \".{2}:.{2}:.{2}:.{2}:.{2}:.{2}\""
        local fd = io.popen(cmd, "r");
        local row = nil
        local mac = nil
        if fd then
            while true do
                local line = nil
                line = fd:read("*l")
                if not line or #line==0 then break end
                row=split(line," ")
                mac = string.upper(row[1])
                res[ mac ] = 1
            end
        end
        fd:close()
    end
    return res
end

function get_client_list() 
    local arp = get_arp()
    local wifilist = get_assoclist()
    local ethlist = {} 
    local s = require "luci.tools.status"
    local leases = s.dhcp_leases()
    local ret = {}
    local str = "" 
    local host_l = {}
    for k,v in pairs(arp) do
       --if 0 == os.execute(string.format("arping %s -I br-lan -f -w 1 >/dev/null",v)) then
       if 0 == os.execute(string.format("ping -I br-lan -c 1 -W 1 %s >/dev/null",v)) then
           ethlist[k] = v
       end
    end
    
    for _, v in pairs(leases) do
        host_l[v.macaddr:upper()] = v
    end
    for k, v in pairs(ethlist) do
        local che = {}
        che.mac = k
        che.ip = v
        if host_l[k] then
            che.host = host_l[k].hostname or "*"
            che.leasetime = host_l[k].expires or 0
        else
            che.host = "*"
            che.leasetime = 0
        end
        if wifilist[k] then
            che.iswifi = 1 
        else
            che.iswifi = 0 
        end
        table.insert(ret,che)
    end
    return ret
end 

function usage()
    print([[usage:getclientlist <-l|-j>
    -l: list format
    -j: json format]])
    os.exit(1)
end
if 1 ~= #arg or ("-l" ~= arg[1] and "-j" ~= arg[1]) then
    usage()
end
local cl = get_client_list()
if "-l" == arg[1] then
    for _,v in pairs(cl) do
        print(string.format("%s %s %s %d %d", v.mac, v.ip, v.host, v.leasetime, v.iswifi))
    end
else
    local json = require("luci.json")
    print(json.encode(cl))
end

